/*
 * Copyright (C) 2009 Show SMS open source project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.bydavy.android.showsms;

//~--- non-JDK imports --------------------------------------------------------

import android.app.Service;

import android.content.Intent;
import android.content.SharedPreferences;

import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Process;

import android.preference.PreferenceManager;

import com.bydavy.model.showsms.SSMessage;
import com.bydavy.util.showsms.Log;

/**
 * This class will queued all intent received by his starting call.
 * Intent queued will by transform in message an send intents.
 *
 * @version        1.0, 09/06/21
 * @author         Davy L.
 */
public class MsgReceivedIntentService extends Service {
    //~--- fields -------------------------------------------------------------

    /** Show SMS enabled status */
    private boolean enabled;

    /** thread that manage SMS received */
    private HandlerThread intentsProcessingThread;

    /** Handler for the intentsProcessingThread */
    private MessageHandler mHandler;

    /** Loop of the intentsProcessingThread */
    private Looper mServiceLooper;

    //~--- methods ------------------------------------------------------------

    /**
     * Create the thread, Handler and load preferences (enabled status)
     *
     */
    @Override
    public void onCreate() {
        super.onCreate();
        Log.v("MsgReceivedIntentService : onCreate");
        loadPreferences();

        // Create the SMS manager thread
        intentsProcessingThread = new HandlerThread("Show SMS HandlerThread", Process.THREAD_PRIORITY_BACKGROUND);
        intentsProcessingThread.start();
        mServiceLooper = intentsProcessingThread.getLooper();
        mHandler       = new MessageHandler(mServiceLooper);
    }

    /**
     * Called on Service destruction
     *
     */
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.v("MsgReceivedIntentService : Destroy");
        mServiceLooper.quit();
    }

    /**
     * Called when the activity try to bind
     *
     * @param arg0
     * @return
     */
    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }

    /**
     * Put the intent in the thread queue
     *
     * @param intent intent to post in the thread queue
     * @param startId service Id kill after message queued processed
     */
    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
        Log.v("MsgReceivedIntentService :onStart()");

        // Shutdown service if Show SMS is not enabled
        if (!enabled) {
            this.stopSelf();
        } else {
            mHandler.processMessage(intent, startId);
        }
    }

    /**
     * Load preferences from SharedPreferences or initialize with default preferences.
     *
     */
    private void loadPreferences() {
        Log.v("MsgReceivedIntentService :loadPreferences()");

        SharedPreferences mySharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

        // loading eula accepted status from SharedPreferences
        boolean eula_def = Boolean.valueOf(getString(R.preferences.eula_def));
        boolean accepted = mySharedPreferences.getBoolean(getString(R.preferences.eula_key), eula_def);

        // loading enabled status from SharedPreferences
        boolean enabled_def = Boolean.valueOf(getString(R.preferences.enabled_def));

        enabled = mySharedPreferences.getBoolean(getString(R.preferences.enabled_key), enabled_def);

        // Don't show the preview if EULA not accepted or SMS Show disabled
        if ((!accepted) | (!enabled)) {
            this.stopSelf();
        }
    }

    //~--- inner classes ------------------------------------------------------

    /**
     * Handler that will process all intent queued
     *
     */
    private final class MessageHandler extends Handler {

        /** Type of message send to the handler queue */
        private static final int MSG_TO_PROCESS = 1;

        /**
         * Service Handler constructor
         *
         * @param looper
         */
        public MessageHandler(Looper looper) {
            super(looper);
        }

        /**
         * To send a message to the handler
         *
         * @param intent intent containing the message to process
         * @param serviceId
         */
        public void processMessage(Intent intent, int serviceId) {
            Message msg = new Message();

            msg.what = MSG_TO_PROCESS;
            msg.arg1 = serviceId;
            msg.obj  = intent;
            mHandler.sendMessage(msg);
        }

        /**
         * Transform the intent contains by the message to a MESSAGE and send intent
         *
         *
         * @param msg message to process
         */
        @Override
        public void handleMessage(Message msg) {
            Log.v("MessageHandler : handleMessage()");

            // Unique type of message for the moment
            if (msg.what == MSG_TO_PROCESS) {
                int       startId  = msg.arg1;
                Intent    intent   = (Intent) msg.obj;
                SSMessage aMessage = SSMessage.extract(intent.getExtras(), getApplicationContext());

                if (aMessage != null) {

                    // starting the preview activity for the message i
                    Intent intentForActivity = new Intent(getApplicationContext(), PreviewActivity.class);

                    intentForActivity.putExtras(aMessage.toBundle());
                    intentForActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
                    startActivity(intentForActivity);
                }

                // Test if there are new messages on queue
                if (this.hasMessages(MSG_TO_PROCESS)) {
                    Log.v("Other messages");
                } else {
                    Log.v("No other messages");

                    // kill the thread that has add this message in the queue
                    // And kill the looper (Handler End Of Life)
                    stopSelf(startId);
                }
            }
        }
    }
}
